package cn.mldn.homework.annotationCreateCRUD;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

public class BaseDao<T>
{

	/*
	 * 通过Bean自动生成insert语句
	 */
	public boolean add(T t)
	{
		Class clazz = t.getClass();// 返回此 t的运行时类。
		
		// 获取表名称
		Table table = (Table) clazz.getDeclaredAnnotation(Table.class);
		String tableName = table.value();

		Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);
		// 获取指定行视图和指定列中的单元格的值
		Set<Entry<Object, Object>> set = columnAndValue.entrySet();

		String keys = "";
		String values = "";
		for (Entry<Object, Object> entry : set)
		{
			if (keys.length() > 0)
			{
				keys += ",";
			}
			if (values.length() > 0)
			{
				values += ",";
			}
			keys += entry.getKey();
			values += "'" + entry.getValue() + "'";
		}
		String sql = "insert into " + tableName + "(" + keys + ") values(" + values + ")";
		System.out.println(sql);
		return true;
	}

	/*
	 * 通过Bean自动生成delete语句
	 */
	public boolean delete(T t)
	{
		Class clazz = t.getClass();
		
		// 获取表名称
		Table table = (Table) clazz.getDeclaredAnnotation(Table.class);
		String tableName = table.value();

		Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);
		// 获取指定行视图和制定列中的单元格的值
		Set<Entry<Object, Object>> set = columnAndValue.entrySet();

		List<Object> primaryKey = getPrimaryKey(clazz);

		String keysAndvalues = "";
		for (Entry<Object, Object> entry : set)
		{
			if (primaryKey.contains(entry.getKey()))
			{
				keysAndvalues += entry.getKey() + " = " + entry.getValue();
			}
		}
		String sql = "delete from " + tableName + " where " + keysAndvalues;
		System.out.println(sql);
		return true;
	}

	/*
	 * 通过Bean自动生成update语句
	 */
	public boolean update(T t)
	{
		Class clazz = t.getClass();
		
		Table table = (Table) clazz.getDeclaredAnnotation(Table.class);
		String tableName = table.value();
		
		Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);
		// 获取指定行视图和制定列中的单元格的值
		Set<Entry<Object, Object>> set = columnAndValue.entrySet();

		List<Object> primaryKey = getPrimaryKey(clazz);
		
		String keysAndvalues = "";
		String FkeysAndvalues = "";

		int i = 1;
		for (Entry<Object, Object> entry : set)
		{

			if (primaryKey.contains(entry.getKey()))
			{
				FkeysAndvalues += " " + entry.getKey() + " = " + entry.getValue();
				i++;
			} else
			{
				if (1 < i && i < set.size())
				{
					keysAndvalues += " and ";
					keysAndvalues += entry.getKey() + " = " + entry.getValue();
				} else
				{
					keysAndvalues += entry.getKey() + " = " + entry.getValue();
					i++;
				}
			}
		}
		String sql = "updata " + tableName + " set " + keysAndvalues + " where" + FkeysAndvalues;
		System.out.println(sql);
		return true;
	}

	/*
	 * 通过Bean自动生成selete语句
	 */
	public boolean selete(T t)
	{
		Class clazz = t.getClass();

		Table table = (Table) clazz.getDeclaredAnnotation(Table.class);
		String tableName = table.value();

		Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);
		// 获取指定行视图和制定列中的单元格的值
		Set<Entry<Object, Object>> set = columnAndValue.entrySet();

		String keysAndvalues = "";
		for (Entry<Object, Object> entry : set)
		{
			if (keysAndvalues.length() > 0)
			{
				keysAndvalues += " and ";
			}
			keysAndvalues += entry.getKey() + " = " + entry.getValue();
		}
		String sql = "selete* from " + tableName + " where " + keysAndvalues;
		System.out.println(sql);
		return true;
	}

	// 按照<列明，属性>的格式输出所有的单元格
	private Map<Object, Object> getColumnAndValue(Class<? extends T> clazz, T t)
	{
		Map<Object, Object> map = new HashMap<>();
		Method[] methods = clazz.getDeclaredMethods();

		for (Method method : methods)
		{
			String methodName = method.getName();
			if (methodName.startsWith("get"))
			{
				// 获得所有的get方法
				Column column = method.getDeclaredAnnotation(Column.class);
				
				try
				{
					map.put(column.value(), method.invoke(t));
				} catch (IllegalAccessException e)
				{
					e.printStackTrace();
				} catch (IllegalArgumentException e)
				{
					e.printStackTrace();
				} catch (InvocationTargetException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		return map;
	}

	private List<Object> getPrimaryKey(Class<? extends T> clazz)
	{
		List<Object> list = new ArrayList<>();
		Field[] fields = clazz.getDeclaredFields();
		// 获得某个类的所有声明字段(id,name,price)
		for (Field field : fields)
		{
			if (field.isAnnotationPresent(PrimaryKey.class))
			{
				// Package.isAnnotationPresent()如果指定类型的注释存在于此元素上,则返回true；否则flase
				PrimaryKey primaryKey = field.getDeclaredAnnotation(PrimaryKey.class);
				try
				{
					list.add(primaryKey.value());
				} catch (IllegalArgumentException e)
				{
					e.printStackTrace();
				}
			}
		}
		return list;
	}
}
